package com.jsbs.iam.user.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jsbs.iam.common.core.utils.PageHelperTool;
import com.jsbs.iam.user.constant.RedisConstants;
import com.jsbs.iam.user.dto.*;
import com.jsbs.iam.user.entity.IamUserTypeBase;
import com.jsbs.iam.user.entity.IamUserTypeExtendedField;
import com.jsbs.iam.user.mapper.UserTypeMapper;
import com.jsbs.iam.user.service.UserTypeService;
import io.netty.util.internal.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @BelongsProject: iam
 * @BelongsPackage: com.jsbs.iam.user.service.impl
 * @Author: WangJiYuan
 * @Description: TODO
 * @Version: 2022-12-20  17:33
 */
@Service
public class UserTypeServiceImpl implements UserTypeService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserTypeServiceImpl.class);

    @Autowired
    private UserTypeMapper userTypeMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Resource
    private RedissonClient redissonClient;

    public static final String PREFIX = "zdbm";
    public static final String PREFIX_TYPE = "fieldCode";
    public static final int NUMLENGTH = 6;
    public static final String KEY_PREFIX = "user";

    @Override
    public List<IamUserTypeBase> getUserTypeData(String companyCode, String userTypeInfo) {
        return userTypeMapper.getUserTypeData(companyCode, userTypeInfo);
    }

    public String getUserTypeIdByRedis(String prefix, int numLength, String type, String companyCode) {
        // 生成用户类型编码加锁，失效时间10分钟
        RLock lock = redissonClient.getLock(RedisConstants.USER_TYPE_CODE_LOCK);
        String returnCode="";
        try {
            String upperCode ="";
            //Redis中存储的key
            String key = KEY_PREFIX + prefix;
            Long size = redisTemplate.opsForList().size(key);//查找 prefix 的key值的数据长度
            if (size > 0) {//有数据
                List leve = redisTemplate.opsForList().range(key, 0, -1);//获取该key下面的所有值(-1 所有的值，；1下一个值
                upperCode = leve.get(leve.size() - 1).toString();//返回最后一个值
            }
            //判断redis中序列是否为空
            if (StringUtils.isEmpty(upperCode)) {
                if ("userTypeCode".equals(type)) {
                    //查询用户类型编码
                    upperCode = userTypeMapper.selectUserTypeId(companyCode);
                } else if ("fieldCode".equals(type)) {
                    //查询用户字段编码
                    upperCode = userTypeMapper.selectUserTypeFieldId(companyCode);
                }
            }
            int Suffix;  //后缀数字
            if (!StringUtil.isNullOrEmpty(upperCode)) { //有数据
                String sequence = upperCode.substring(prefix.length());//截取前缀开始的后面的数字
                Suffix = Integer.parseInt(sequence);
                Suffix++;//最后的序号加一
            } else {
                Suffix = 1;//没有数据
            }
            returnCode = prefix + String.format("%0" + numLength + "d", Suffix);//后缀不够numLength长，前面补充0
            redisTemplate.opsForList().rightPush(key, returnCode);//存入Redis
        } catch (Exception e) {
            LOGGER.error("Route=>UserTypeServiceImpl method=>getUserTypeIdByRedis 用户类型,系统自动生成编码失败:", e);
            throw new RuntimeException("用户类型,系统自动生成编码异常");
        } finally {
            // 手动解锁
            if (lock.isLocked()) {
                lock.unlock();
            }
        }
        return  returnCode;
    }

    @Override
    public int checkName(String userTypeInfo, String companyCode) {
        return userTypeMapper.checkName(userTypeInfo,companyCode);
    }

    @Override
    public void addUserType(UserTypeAddDto userTypeAddDto) {
        userTypeAddDto.setUserTypeCode(this.getUserTypeIdByRedis("yhlx",6,"userTypeCode",userTypeAddDto.getCompanyCode()));
        userTypeMapper.addUserType(userTypeAddDto);
    }

    @Override
    public int checkUserCount(String userTypeCode, String companyCode) {
        //校验用户类型下是否有用户
        return userTypeMapper.checkUserCount(userTypeCode,companyCode);
    }

    @Override
    @Transactional
    public void deleteUserType(UserTypeDeleteDto deleteDto) {
        //删除用户类型基础数据
        userTypeMapper.deleteUserType(deleteDto);
        //删除用户类型字段数据
        userTypeMapper.deleteUserTypeFieldData(deleteDto);
        //删除用户类型字段保存的数据  删除用户时 已经删除此数据
        //userTypeMapper.deleteUserTypeExtendData(deleteDto);
    }

    @Override
    public PageInfo selectUserTypeFieldList(UserTypeFieldSelectDto userTypeFieldSelectDto) {
        userTypeFieldSelectDto.init();
        PageHelper.startPage(userTypeFieldSelectDto.getCurrPage(), userTypeFieldSelectDto.getPageSize());
        //查询对应用户类型下所有字段
        List<IamUserTypeExtendedField> list = userTypeMapper.selectUserTypeFieldList(userTypeFieldSelectDto);
        PageInfo<IamUserTypeExtendedField> page = new PageInfo<>(list);
        PageInfo<IamUserTypeExtendedField> pageInfo =
                PageHelperTool.initPageInfoObj(userTypeFieldSelectDto.getCurrPage(), (int) page.getTotal(), userTypeFieldSelectDto.getPageSize(), page);
        return pageInfo;
    }

    @Override
    public void addUserTypeField(UserTypeFieldAddDto userTypeFieldAddDto) {
        //从Redis中获取自增序列
        String fieldId = this.getUserTypeIdByRedis(PREFIX, NUMLENGTH, PREFIX_TYPE, userTypeFieldAddDto.getCompanyCode());
        userTypeFieldAddDto.setFieldId(fieldId);
        //新增用户类型字段
        userTypeMapper.addUserTypeField(userTypeFieldAddDto);
    }

    @Override
    public void updateUserTypeField(UserTypeFieldUpdateDto userTypeFieldUpdateDto) {
        userTypeMapper.updateUserTypeField(userTypeFieldUpdateDto);
    }

    @Override
    @Transactional
    public void deleteUserTypeField(UserTypeFieldUpdateDto userTypeFieldUpdateDto) {
        if (userTypeFieldUpdateDto.getFieldIds().size() > 0) {
            //根据字段id逻辑删除用户类型字段
            userTypeMapper.deleteUserTypeFieldById(userTypeFieldUpdateDto);
            //根据id逻辑删除用户类型字段存储的数据
            userTypeMapper.deleteUserTypeFieldValueById(userTypeFieldUpdateDto);
        }
    }
}
